package com.hk.service.order.impl;

import com.hk.commons.*;
import com.hk.commons.entity.Agreement;
import com.hk.commons.entity.Answer;
import com.hk.commons.entity.Parameter;
import com.hk.commons.entity.PaymentReplaceField;
import com.hk.commons.entity.order.OrderContract;
import com.hk.commons.entity.order.OrderInfo;
import com.hk.commons.entity.product.ProductInfo;
import com.hk.commons.entity.sys.SysUser;
import com.hk.dao.base.impl.BaseServiceImpl;
import com.hk.service.kyc.IAgreement;
import com.hk.service.kyc.ICoupon;
import com.hk.service.order.IOrderContract;
import com.hk.service.order.IOrderInfo;
import com.hk.service.order.IParameter;
import com.hk.service.order.IPayment;
import com.hk.service.product.IProductInfo;
import com.hk.service.sys.IAnswer;
import com.hk.service.sys.ISysUser;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.itextpdf.tool.xml.html.CssAppliers;
import com.itextpdf.tool.xml.html.CssAppliersImpl;
import com.itextpdf.tool.xml.html.Tags;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.*;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

@Service
public class OrderContractImpl extends BaseServiceImpl<OrderContract> implements IOrderContract {
	private Logger logger = LoggerFactory.getLogger(OrderContractImpl.class);

	@Value("${pdf.address}")
	private String FILE_DIR;

	@Value("${pdf.FTP_URL}")
	private String FTP_URL;

	@Value("${pic.address}")
	private String PIC_ADDRESS;


	@Value("${pic.tzqrh_back_img}")
	private String TZQRH_BACK_IMG;

	@Value("${pic.tzqrh_yz_img}")
	private String TZQRH_YZ_IMG;

	@Value("${qingniu.pdf}")
	private String QM_PDF;
	@Autowired
	private IOrderInfo orderService;

	@Autowired
	private IProductInfo productService;


	@Autowired
	private IAgreement agreementService;

	@Autowired
	private IParameter parmService;

	@Autowired
	private ISysUser userService;

	@Autowired
	private IAnswer answerService;

	@Autowired
	ICoupon couponService;

	@Autowired
	IPayment paymentService;

	@Autowired
	JdbcTemplate jdbcTemplate;

    @Override
    public Boolean createByOrderId(long orderId) {
        OrderInfo order = orderService.findById(orderId);

        List<Long> contractList = productService.getAgreementIds(order.getProductId());
        if (contractList == null) {
            logger.info("create order contract failed contractList is null orderId={}", orderId);
            return false;
        }

        BlockingQueue<Long> orderContractQueue = new LinkedBlockingQueue<Long>();

        contractList.parallelStream()
                .forEach(contractId -> {
                    try {
                        orderContractQueue.put(contractId);
                    } catch (InterruptedException e) {
                        logger.error("gen pdf: contractId={} orderId={} ContractQueue Error :", contractId, orderId, e);
                    }
                });

        ExecutorService executor = Executors.newFixedThreadPool(1);
        Runnable task = () -> createContract(orderContractQueue,orderId);
        executor.execute(task);
        executor.shutdown();

        return true;
    }

    private void createContract(BlockingQueue<Long> orderContractQueue, Long orderId) {
        if (orderContractQueue == null || orderContractQueue.size() <= 0) {
            return;
        }

        try {
            while (orderContractQueue.size() > 0) {
                Long contractId = orderContractQueue.take();

                createPDFByContract(orderId, contractId);
            }
        } catch (Exception e) {
            logger.error("Create Order ={} Contract Error: {}", orderId, e);
        }

    }

    private Boolean createPDFByContract(long orderId, Long contractId) {
        Boolean result = this.createOne(orderId, contractId);
        if (!result) {
            logger.error("create order contract failed orderId={}, contractId={}", orderId, contractId);
            return result;
        }

        logger.info("create order contract failed orderId={}, contractId={}", orderId, contractId);
        return null;
    }

	@Override
	public Boolean createOne(long orderId, long contractId) {

		Agreement agreement = agreementService.findById(contractId);

		if(agreement == null){
			return false;
		}
		OrderContract orderContract = new OrderContract();
		orderContract.setId(LongId.get());
		orderContract.setOrderId(orderId);
		orderContract.setContractID(contractId);
		orderContract.setContractTitle(agreement.getName());
		orderContract.setContractPDFUrl(this.getPDFContarctUrlByOrder(orderId,contractId));
		orderContract.setContractHTMLUrl(this.getHTMLContarctUrlByOrder(orderId,contractId));
		orderContract.setCts(System.currentTimeMillis());

		if(StringHelper.isEmpty(orderContract.getContractHTMLUrl()) && StringHelper.isEmpty(orderContract.getContractPDFUrl())){
			logger.error("both pdf and HTML contract document create faile! orderId ={}, contractId ={}", orderId, contractId);
			return false;
		}

		super.save(orderContract);
		return true;
	}

	@Override
	public List<OrderContract> getOrderContractList(long orderId) {
		HqlFilter hqlFilter = new HqlFilter();
		hqlFilter.addEQFilter("orderId", orderId);

		List<OrderContract> contractList = this.findByFilter(hqlFilter);

		//排序
		Collections.sort(contractList);

		return contractList;
	}

	@Override
	public String getPDFContarctUrlByOrder(long orderId, long contractId) {
		OrderInfo order = orderService.findById(orderId);
		String pdfUrl = this.createContractPDFByOrder(orderId, contractId);

		return pdfUrl;
	}

	@Override
	public void sign(String source01, String source02 )  {
		try{
			PdfReader reader = new PdfReader(source01);//选择需要印章的pdf
			PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(source02));//加完印章后的pdf
			PdfContentByte over = stamp.getOverContent(1);//设置在第几页打印印章
			Image img = Image.getInstance(TZQRH_YZ_IMG);//选择图片
			img.setAlignment(1);
			img.scaleAbsolute(130,130);//控制图片大小
			img.setAbsolutePosition(400,170);//控制图片位置
			over.addImage(img);
			stamp.close();
			logger.info("添加印章完成");
		}catch(Exception e){
			logger.info("添加电子印章错误 e={}", e);
		}
	}

	@Override
	public void sign(String source01, String source02, Integer pageNum )  {
		try{
			PdfReader reader = new PdfReader(source01);//选择需要印章的pdf
			PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(source02));//加完印章后的pdf
			PdfContentByte over = stamp.getOverContent(pageNum);//设置在第几页打印印章
			Image img = Image.getInstance(TZQRH_YZ_IMG);//选择图片
			img.setAlignment(1);
			img.scaleAbsolute(130,130);//控制图片大小
			img.setAbsolutePosition(50,500);//控制图片位置
			over.addImage(img);
			stamp.close();
			logger.info("添加印章完成");
		}catch(Exception e){
			logger.info("添加电子印章错误 e={}", e);
		}
	}


	private String getCode(){
		String code = "";
		Random random = new Random();
		for (int i = 0; i < 12; i++) {
			code += random.nextInt(10);
		}
		return code;
	}

	/**
	 * 获取多少位的随机码
	 * @param num 数位
	 * @return
	 */
	private String getRandom(int num){
		String code = "";
		Random random = new Random();
		for(int i = 0;i<num;i++){
			code += random.nextInt(10);
		}
		return code;
	}

	@Override
	public String getHtmlContent( String content) {
		String result = "";
		try{
			StringBuilder sb = new StringBuilder();
			sb.append("<html>");
			sb.append("<head>");
			//sb.append("<title>每日运营报表</title>");
			sb.append("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=2.0, user-scalable=yes \" />");

			sb.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />");

			sb.append("</head><body><div style=\"width: 100%; word-break:break-all;\">");

			content = content.replace("/upload/ueditor/jsp/upload/image/", PIC_ADDRESS);

			sb.append(content);
			sb.append("</div></body></html>");
			result = sb.toString();

		}catch ( Exception e){
			logger.info("create excel exception e={}", e);
		}

		return result;
	}


	@Override
	public String getKycPdfUrl(long userId) {

		Long contractId = getKycContractId();
		Answer answer = answerService.getByUserId(userId);

		return this.createContractPDFByUser(userId, contractId, answer.getCts());
	}

	@Override
	public String getKycHTMLUrl(long userId) {
		Answer answer = answerService.getByUserId(userId);
		String htmlContractUrl = this.getHTMLContarctUrlByUser(userId, answer.getCts());
		return htmlContractUrl;
	}


	private Long  getKycContractId(){
		Parameter parm = parmService.getByName("KYC_CONTRSCT_ID");

		if(parm == null || StringHelper.isEmpty(parm.getValue01())){
			logger.error("kyc pdf contract parameter is not setk, pls set parameter KYC_CONTRSCT_ID");
			return null;
		}

		Long contractId = Long.valueOf(parm.getValue01());

		return contractId;
	}

	//创建HTML文件
	@Override
	public String getHTMLContarctUrlByOrder(long orderId, long contractId) {

		logger.info("creatHTMLFile contract orderId ={}", orderId);

		String pathName = getCode() + ".html";

		logger.info("pathName = {}", pathName);



		OrderInfo orderInfo = orderService.findById(orderId);

		String contractUrl = null;
		if(orderInfo == null){
			return null;
		}

		Long productId = orderInfo.getProductId();

		ProductInfo productInfo = productService.findById(productId);
		if(productInfo == null){
			return null;
		}

		String contractMsg = agreementService.getByInfo(contractId, orderInfo.getUserId(), orderInfo.getSuccessAmount().toString());

		//替换订单id
		contractMsg = contractMsg.replace("88888888", String.valueOf(orderId));

		contractMsg = contractMsg.replace("prodName", productInfo.getName());

		if(!StringUtils.isBlank(productInfo.getLicenseNumber())) {
			contractMsg = contractMsg.replace("licenseNumber", productInfo.getLicenseNumber());
		}

		//替换t_payment表卡状态、userId
		contractMsg = getPaymentInfo(orderId, contractMsg);


		//替换产品相关信息
		String agreementProductName = productInfo.getAgreementProductName();
		if(StringUtils.isBlank(agreementProductName)){
			agreementProductName = productInfo.getName();
		}
		contractMsg = contractMsg.replace("agreementProductName",agreementProductName);
		contractMsg = contractMsg.replace("proTerm",productInfo.getProTermStr());
		contractMsg = contractMsg.replace("maxYearRate",productInfo.getMaxYearRate());
		//挂牌号
		if(StringUtils.isNotBlank(productInfo.getListingNumber())){
			contractMsg = contractMsg.replace("listingNumber",productInfo.getListingNumber());
		}


		String contractContent = getHtmlContent(contractMsg);
		logger.info("creatHTMLFile pathName ={}", pathName);
		try {
			Path filePath = Paths.get(pathName);
			Files.write(filePath, contractContent.getBytes("UTF-8"));
		} catch (IOException e) {
			logger.error("创建订单HTML 失败 orderId={}, e={}", orderId,  e);
		}

		String respStr = ftpSave(pathName, pathName, true);

		logger.info("创建订单HTML respStr = " + respStr);
		org.codehaus.jackson.JsonNode result = JsonUtils.toJsonObject(respStr);

		contractUrl = this.getURLFromResult(result,  pathName);

		if(StringHelper.isEmpty(contractUrl)){
			pathName = null;
		}

		return pathName;
	}

	//创建HTML文件
	@Override
	public String getHTMLContarctUrlByUser(long userId, long timeLong) {

		String pathName = getCode() + ".html";

		String contractMsg = this.getUserKycMsg(userId, getKycContractId(), timeLong);

		String contractContent = getHtmlContent(contractMsg);
		logger.info("creatHTMLFile pathName ={}", pathName);
		try {
			Path filePath = Paths.get(pathName);
			Files.write(filePath, contractContent.getBytes("UTF-8"));
		} catch (IOException e) {
			logger.error("创建订单HTML 失败 user ID ={}, e={}", userId,  e);
		}

		String respStr = ftpSave(pathName, pathName, true);

		org.codehaus.jackson.JsonNode result = JsonUtils.toJsonObject(respStr);

		String contractUrl = this.getURLFromResult(result,  pathName);

		if(StringHelper.isEmpty(contractUrl)){
			pathName = null;
		}
		return pathName;
	}


	@Override
	public String  getTZQRHPDFUrl(Long orderId) {
		OrderInfo orderInfo = orderService.findById(orderId);

		if (orderInfo == null) {
			return null;
		}

		Long productId = orderInfo.getProductId();

		ProductInfo productInfo = productService.findById(productId);
		if (productInfo == null) {
			return null;
		}

		//获取投资确认函ID
		Long agreementId = agreementService.getTQRHId();

		String contractMsg = agreementService.getByInfo(agreementId, orderInfo.getUserId(), orderInfo.getSuccessAmount().toString());

		contractMsg = contractMsg.replace("88888888", String.valueOf(orderId));


		Long tradeDate = orderInfo.getOrderTradeDate();

		String tradeDateStr01 = DateUtil.longToShortDate(tradeDate);

		String tradeDateStr02 = DateUtil.longToShortDateZW(tradeDate);

		logger.info("contractMag = {}", contractMsg);

		//替换起息日
		contractMsg = contractMsg.replace("tradeDate01", tradeDateStr01);
		contractMsg = contractMsg.replace("tradeDate02", tradeDateStr02);

		//替换投资金额
		BigDecimal buyAmount = orderInfo.getSuccessAmount();

		contractMsg = contractMsg.replace("amount01", MoneyUtil.number2CNMontrayUnit(buyAmount));
		contractMsg = contractMsg.replace("amount02", buyAmount.toString());


        //如果历史订单没有投资期限,读取产品本身的投资期限
        if (orderInfo.getTerm() != null) {
            //替换投资期限
            contractMsg = contractMsg.replace("term", orderInfo.getTerm().toString());
        } else {
           if(productInfo.getProTerm() != null){
               contractMsg = contractMsg.replace("term", productInfo.getProTerm().toString());
           }
        }

        //替换产品名称
		contractMsg = contractMsg.replace("prodName", productInfo.getName());

		if (StringHelper.isNotEmpty(orderInfo.getContractTitle())) {
			//替换合同名称
			contractMsg = contractMsg.replace("contractTitle", orderInfo.getContractTitle());
		} else {
			String content = "电子合同";
			//如果订单没有生成电子合同
			Agreement agr = agreementService.findById(productInfo.getContractId());
			if (agr != null) {
				content = agr.getName();
			}

			contractMsg = contractMsg.replace("contractTitle", content);

		}

		//替换空格占位符,一个#代表半个空格占位符
		contractMsg = contractMsg.replace("#", " ");

		//替换产品相关信息
		String agreementProductName = productInfo.getAgreementProductName();
		if(StringUtils.isBlank(agreementProductName)){
			agreementProductName = productInfo.getName();
		}
		contractMsg = contractMsg.replace("agreementProductName",agreementProductName);
		contractMsg = contractMsg.replace("proTerm",productInfo.getProTermStr());
		contractMsg = contractMsg.replace("maxYearRate",productInfo.getMaxYearRate());
		//挂牌号
		if(StringUtils.isNotBlank(productInfo.getListingNumber())){
			contractMsg = contractMsg.replace("listingNumber",productInfo.getListingNumber());
		}

		//add========
		contractMsg = getPaymentInfo(orderId, contractMsg);

		try {
			//页面大小
			Rectangle rect = new Rectangle(PageSize.A4);


			//页面背景色
			rect.setBackgroundColor(BaseColor.WHITE);

			Document document = new Document(rect);

			//不带印章的文件
			String filePath = orderId + "_confirm_" + getCode() + ".pdf";

			String filePath_yz = getCode() + ".pdf";

			//Step 2—Get a PdfWriter instance.
			PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filePath));

			//Step 3—Open the Document.
			document.open();

			Image tImgCover = Image.getInstance(TZQRH_BACK_IMG);

            /* 设置图片的位置 */
			tImgCover.setAbsolutePosition(0, 0);

            /* 设置图片的大小 */
			tImgCover.scaleAbsolute(PageSize.A4); // .scaleAbsolute(595, 842);
			document.add(tImgCover);

			InputStream inputStream = new ByteArrayInputStream(this.getHtmlContent(contractMsg).getBytes("UTF-8"));

			// 使用我们的字体提供器，并将其设置为unicode字体样式
			MyFontsProvider fontProvider = new MyFontsProvider();
			fontProvider.addFontSubstitute("lowagie", "garamond");
			fontProvider.setUseUnicode(true);
			CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
			HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
			htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());

			XMLWorkerHelper.getInstance().getDefaultCssResolver(true);

			XMLWorkerHelper.getInstance().parseXHtml(writer, document, inputStream, null, Charset.forName("UTF-8"),
					fontProvider);

			logger.info("投资确认函 pdf will create ");
			//XMLWorkerHelper. getInstance().parseXHtml(writer, document,  inputStream, Charset.forName("UTF-8"));

			logger.info("投资确认函 pdf create finished");

			// step 5
			document.close();
			writer.close();

			logger.info("投资确认函 pdf will close");

			sign(filePath, filePath_yz);

			String respStr = ftpSave(filePath_yz, filePath_yz, true);

			logger.info("respStr = " + respStr);
			org.codehaus.jackson.JsonNode result = JsonUtils.toJsonObject(respStr);


			String confirmPDFUrl = this.getURLFromResult(result, filePath);

			logger.info("投资确认函 pdfUrl =  {}, orderId={}", confirmPDFUrl, orderId);
			if (StringHelper.isNotEmpty(confirmPDFUrl)) {

				// create pdf take long time, get latest record for update
				orderInfo = orderService.findById(orderId);
				orderInfo.setConfirmationTitle("投资确认函");
				orderInfo.setConfirmationPdf(filePath_yz);
				orderService.update(orderInfo);

				// 删除未带印章带pdf
				File file = new File(filePath);
				if (file.isFile() && file.exists()) {
					file.delete();
					logger.info("contract will delete contract FILE  = {}", filePath);
				}

                return filePath_yz;
			}

		} catch (Exception e) {
			logger.info("create pdf exception e={}", e);
			return null;
		}
		return null;
	}


	public String getURLFromResult(org.codehaus.jackson.JsonNode result,  String pathName){
		String contractUrl = null;
		if(result.get("success").getBooleanValue()){

			logger.info("get order contract HTML success.");

			contractUrl = result.get("file_path").toString();
		}
		return contractUrl;
	}

	/**
	 * 重写 字符设置方法，解决中文乱码问题
	 *
	 */
	public class MyFontsProvider extends XMLWorkerFontProvider {

		public MyFontsProvider(){
			super(null, null);
		}

		@Override
		public Font getFont(final String fontname, String encoding, float size, final int style) {

			String fntname = "WenQuanYi Zen Hei";


			if (size == 0) {
				size = 4;
			}
			return super.getFont(fntname, encoding, size, style);
		}
	}

	@Override
	public String ftpSave(String filePath, String fileName, Boolean ifDelete){
		logger.info("in ftpSave fileName={}, ifDelete={}", fileName, ifDelete);
		RestTemplate rest = new RestTemplate();
		FileSystemResource resource = new FileSystemResource(new File(filePath));
		MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
		param.add("upload_file", resource);
		param.add("contract_id", fileName);

		String ftpResult = rest.postForObject(FTP_URL, param, String.class);


		logger.info("创建订单HTML respStr = " + ftpResult);
		org.codehaus.jackson.JsonNode result = JsonUtils.toJsonObject(ftpResult);

		String contractUrl = this.getURLFromResult(result,  fileName);
		if(StringHelper.isNotEmpty(contractUrl) && ifDelete){
			File file = new File(filePath);
			if (file.isFile() && file.exists()) {
				file.delete();
				logger.info("contract will delete contract FILE  = {}", filePath);
			}
		}


		return ftpResult;
	}

	@Override
	public String createContractPDFByOrder(long orderId, long contractId){
		String contractMsg = this.getContractMsgByOrder(orderId, contractId);


		String filePath = createPDFDocument(contractMsg,orderId,contractId);
		return filePath;
	}

	@Override
	public String createContractPDFByUser(long userId, long contractId, long timeLong) {
		String contractMsg = this.getUserKycMsg(userId, contractId, timeLong);
		String filePath = createPDFDocument(contractMsg,null,contractId);
		return filePath;
	}

	/**
	 * 生成PDF文档，并返回链接
	 * @param contractMsg
	 * @return
     */
	@Override
	public String createPDFDocument(String contractMsg,Long orderId,Long contractId){
		String fileName;
		if(orderId ==null){
			fileName = getCode() + ".pdf";
		}else{
			fileName = contractId+"-"+orderId+"-"+getRandom(6)+".pdf";
		}

		String createResult;
		try {
			createResult = createPDFDocument(contractMsg, fileName, true);
		}catch ( Exception e){
			logger.info("create pdf exception e={}", e);
			return null;
		}

		return createResult;
	}

	//生成风险测评
	private String getUserKycMsg(Long userId, Long kycAgreementId, Long timeLong){
		String contractMsg = null;
		try {
			Agreement ag = agreementService.findById(kycAgreementId);
			if (ag == null && ag.getAgreement() == null) {
				return null;
			}

			contractMsg = new String(ag.getAgreement(), "UTF-8");

			SysUser user = userService.findById(userId);

			Answer answer = answerService.getByUserId(userId);


			if(StringHelper.isNotEmpty(user.getRealName())){
				contractMsg = contractMsg.replace("userName", user.getRealName());
			}


			if(StringHelper.isNotEmpty(user.getIdentity())){
				contractMsg = contractMsg.replace("idNum", user.getIdentity());
			}

			if(StringHelper.isNotEmpty(answer.getScoreDesc())){
				contractMsg = contractMsg.replace("riskLevel", answer.getScoreDesc());
			}


			contractMsg = contractMsg.replace("nowDate", DateUtil.getCurTimeStr(timeLong));


			String userKycAnswer = answer.getAnswerArray();
			if (StringHelper.isNotEmpty(userKycAnswer)) {
				String[] userKycAnswerArray = userKycAnswer.split(",");

				//替换第1个答案
				contractMsg = contractMsg.replace("answer01", switchCode(userKycAnswerArray[0]));

				//替换第2个答案
				contractMsg = contractMsg.replace("answer02", switchCode(userKycAnswerArray[1]));

				//替换第3个答案
				contractMsg = contractMsg.replace("answer03", switchCode(userKycAnswerArray[2]));

				//替换第4个答案
				contractMsg = contractMsg.replace("answer04", switchCode(userKycAnswerArray[3]));

				//替换第5个答案
				contractMsg = contractMsg.replace("answer05", switchCode(userKycAnswerArray[4]));

				//替换第6个答案
				contractMsg = contractMsg.replace("answer06", switchCode(userKycAnswerArray[5]));

				//替换第7个答案
				contractMsg = contractMsg.replace("answer07", switchCode(userKycAnswerArray[6]));

				//替换第8个答案
				contractMsg = contractMsg.replace("answer08", switchCode(userKycAnswerArray[7]));

				//替换第9个答案
				contractMsg = contractMsg.replace("answer09", switchCode(userKycAnswerArray[8]));

				//替换第10个答案
				contractMsg = contractMsg.replace("answer10", switchCode(userKycAnswerArray[9]));
			}


		} catch (Exception e) {
			logger.error("getContractMsgByUserId exception e={}", e);
		}
		return contractMsg;
	}

	private String getContractMsgByOrder(Long orderId, Long contractId){
		OrderInfo orderInfo = orderService.findById(orderId);

		if(orderInfo == null){
			return null;
		}

		Long productId = orderInfo.getProductId();

		ProductInfo productInfo = productService.findById(productId);

		if(productInfo == null){
			return null;
		}

		String contractMsg = agreementService.getByInfo(contractId, orderInfo.getUserId(), orderInfo.getSuccessAmount().toString());

		//替换订单id
		contractMsg = contractMsg.replace("88888888", String.valueOf(orderId));

		//替换还产品名称
		contractMsg = contractMsg.replace("prodName", productInfo.getName());

		//替换产品相关信息
		String agreementProductName = productInfo.getAgreementProductName();
		if(StringUtils.isBlank(agreementProductName)){
			agreementProductName = productInfo.getName();
		}
		contractMsg = contractMsg.replace("agreementProductName",agreementProductName);
		contractMsg = contractMsg.replace("proTerm",productInfo.getProTermStr());
		contractMsg = contractMsg.replace("maxYearRate",productInfo.getMaxYearRate());
		//挂牌号
		if(StringUtils.isNotBlank(productInfo.getListingNumber())){
			contractMsg = contractMsg.replace("listingNumber",productInfo.getListingNumber());
		}

		if(!StringUtils.isBlank(productInfo.getLicenseNumber())) {
			contractMsg = contractMsg.replace("licenseNumber", productInfo.getLicenseNumber());
		}

		//通过userId查 t_payment
		contractMsg = getPaymentInfo(orderId, contractMsg);

		return contractMsg;
	}

	/**
	 * 从数据库中取出 payment表信息
	 * @param orderId
	 * @param contractMsg
	 * @return
	 */
	private String getPaymentInfo(Long orderId, String contractMsg) {
		String paymentNoStr="";
		String bankNameStr="";
		String strCardStatus_1 ="SELECT paymentNo,bankName from t_payment where userId in (SELECT userId from t_order_info where id = "+orderId+") and cardStatus = 1 and supportCompany like '1%' ";
		String strCardStatus_10 = "SELECT paymentNo,bankName from t_payment where userId in (SELECT userId from t_order_info where id = "+orderId+") and cardStatus = 10 and supportCompany like '1%' ";
		List<PaymentReplaceField> paymentReplaceField_1 = jdbcTemplate.query(strCardStatus_1.toString(),new BeanPropertyRowMapper<>(PaymentReplaceField.class));
		if(paymentReplaceField_1.size() != 0) {
			paymentNoStr = paymentReplaceField_1.get(0).getPaymentNo();
			bankNameStr = paymentReplaceField_1.get(0).getBankName();
		}else {
			List<PaymentReplaceField> paymentReplaceField_2 = jdbcTemplate.query(strCardStatus_10.toString(),new BeanPropertyRowMapper<>(PaymentReplaceField.class));
			if(paymentReplaceField_2.size() != 0) {
				paymentNoStr = paymentReplaceField_2.get(0).getPaymentNo();
				bankNameStr = paymentReplaceField_2.get(0).getBankName();
			}
		}

		//银行卡号
		if(!StringUtils.isBlank(paymentNoStr)) {
			contractMsg = contractMsg.replace("paymentNo",paymentNoStr);
		}

		//银行名称
		if(!StringUtils.isBlank(bankNameStr)) {
			contractMsg = contractMsg.replace("bankName",bankNameStr );
		}

		return contractMsg;
	}


	@Override
	public String createHTMLDocument(String contractMsg, Long orderId, Long contractId) {
		String fileName;

		if(orderId != null && contractId != null){
			fileName = contractId+"-"+orderId+"-"+getRandom(6)+".pdf";
		}else{
			fileName = getCode() + ".pdf";
		}

		return createHTMLDocument(contractMsg, fileName, true);
	}


	@Override
	public String createHTMLDocument(String contractMsg, String fileName, Boolean ifDelete) {

		logger.info("creatHTMLFile fileName ={}", fileName);

		try {
			Path filePath = Paths.get(fileName);
			Files.write(filePath, contractMsg.getBytes("UTF-8"));
		} catch (IOException e) {
			logger.error("创建HTML失败", e);
		}

		String respStr = ftpSave(fileName, fileName, ifDelete);

		logger.info("创建订单HTML respStr = " + respStr);
		org.codehaus.jackson.JsonNode result = JsonUtils.toJsonObject(respStr);

		String contractUrl = this.getURLFromResult(result,  fileName);

		if(StringHelper.isEmpty(contractUrl)){
			fileName = null;
			logger.error("ftp保存html文档失败");
		}

		return fileName;


	}

	@Override
	public String createPDFDocument(String contractMsg, String fileName, Boolean ifDelete) {
		logger.info("createPDFDocument fileName={}, ifDelete={}", fileName, ifDelete);

		String contractUrl;
		try {
			//页面大小
			Rectangle rect = new Rectangle(PageSize.A4);

			//页面背景色
			rect.setBackgroundColor(BaseColor.WHITE);

			Document document = new Document(rect);

			logger.info("fileName = {}", fileName);
			//Step 2—Get a PdfWriter instance.
			PdfWriter writer =  PdfWriter.getInstance(document, new FileOutputStream(fileName));

			//Step 3—Open the Document.
			document.open();

			InputStream inputStream = new ByteArrayInputStream(this.getHtmlContent(contractMsg).getBytes("UTF-8"));


			// 使用我们的字体提供器，并将其设置为unicode字体样式
			MyFontsProvider fontProvider = new MyFontsProvider();
			fontProvider.addFontSubstitute("lowagie", "garamond");
			fontProvider.setUseUnicode(true);
			CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
			HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
			htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());

			XMLWorkerHelper.getInstance().getDefaultCssResolver(true);

			XMLWorkerHelper.getInstance().parseXHtml(writer, document, inputStream, null, Charset.forName("UTF-8"),
					fontProvider);

			logger.info("pdf will create ");
			//XMLWorkerHelper. getInstance().parseXHtml(writer, document,  inputStream, Charset.forName("UTF-8"));

			logger.info("pdf create finished");

			// step 5
			document.close();
			writer.close();

			logger.info("pdf will close");

			String respStr = ftpSave(fileName, fileName, ifDelete);

			logger.info("respStr = " + respStr);
			org.codehaus.jackson.JsonNode result = JsonUtils.toJsonObject(respStr);

			contractUrl = this.getURLFromResult(result, fileName);

		}catch ( Exception e){
			logger.info("create pdf exception e={}", e);
			return null;
		}

		logger.info("04 contractUrl={}", contractUrl);
		if(StringHelper.isEmpty(contractUrl)){
			fileName = null;
			logger.error("ftp 生成pdf错误");
			return  fileName;
		}

		return fileName;
	}

	public String switchCode(String code) {
		String newCode = "";
		if (code.equals("1")) {
			newCode =  "A";
		} else if (code.equals("2")) {
			newCode =  "B";
		} else if (code.equals("3")) {
			newCode =  "C";
		} else if (code.equals("4")) {
			newCode =  "D";
		} else if (code.equals("5")) {
			newCode =  "E";
		} else if (code.equals("6")) {
			newCode = "F";
		}

		return newCode;
	}

    @Override
    public HashMap reCreatePDFAndHTMLForSameContract(Long contractId){
        HashMap result = new HashMap();

        HqlFilter hqlFilter = new HqlFilter();
        hqlFilter.addEQFilter("contractID", contractId);

        List<OrderContract> contractList = this.findByFilter(hqlFilter);

        if(contractList == null || contractList.size()<=0){
            result.put("ERROR","No Contract Found!");
            return result;
        }

        contractList
                .stream()
                .forEach(orderContract -> {
                    reCreateForOneOrder(result, orderContract);
                });

        return result;
    }

    private void reCreateForOneOrder( HashMap result, OrderContract orderContract) {
        Long orderId = orderContract.getOrderId();
        Long contractId = orderContract.getContractID();

        Boolean needUpdate = false;

        if (StringUtils.isBlank(orderContract.getContractHTMLUrl())) {
            String htmlUrl = this.getHTMLContarctUrlByOrder(orderId, contractId);
            orderContract.setContractHTMLUrl(htmlUrl);
            result.put(orderId+"-HTML",htmlUrl);
            needUpdate = true;
        }

        if (StringUtils.isBlank(orderContract.getContractPDFUrl())) {
            String pdfUrl = this.getPDFContarctUrlByOrder(orderId, contractId);
            orderContract.setContractPDFUrl(pdfUrl);
            result.put(orderId+"-PDF",pdfUrl);
            needUpdate = true;
        }

        if(needUpdate){
            super.update(orderContract);
        }
    }
}
